// Copyright 2013 Petar Maymounkov
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// ztailevent is a command-line tool that connects to Zookeeper and prints out session events
package main

import (
	"circuit/kit/zookeeper/zutil"
	"flag"
	"fmt"
	"time"
)

var (
	flagZookeepers = flag.String("z", "localhost:9090", "Zookeeper workers string (colon-separated)")
)

/*
(disconnect shortly)
•Session event: ZooKeeper connecting
(reconnect)
•Session event: ZooKeeper connected
(disconnect long time)
•Session event: ZooKeeper connecting
(reconnect)
•Session event: ZooKeeper session expired

XXX: ChildrenChange seems to return right away?

--------------------------------------------------------------------------------------------------
Dialing Zookeeper…
Installing watch.
Fetching children first time.
children=[]string{"circuit", "zookeeper"}
Sleeping 2 seconds before second watch …
•Session event: ZooKeeper connecting
ChildrenChange <-cwatch event=zookeeper.Event{Type:-1, Path:"", State:-112}
panic: zookeeper: childrenw "/": invalid zhandle state

goroutine 1 [running]:
main.main()
/Users/petar/code.google.com/p/gocircuit/src/circuit/kit/zookeeper/zutil/ztailevent/main.go:68 +0x353

goroutine 2 [syscall]:

goroutine 4 [syscall]:
circuit/kit/zookeeper._Cfunc_wait_for_watch(0x0)
circuit/kit/zookeeper/_obj/_cgo_defun.c:475 +0x2f
circuit/kit/zookeeper._watchLoop()
circuit/kit/zookeeper/_obj/_cgo_gotypes.go:1337 +0x1c
created by circuit/kit/zookeeper.runWatchLoop
circuit/kit/zookeeper/_obj/_cgo_gotypes.go:1310 +0x42

goroutine 5 [runnable]:
circuit/kit/zookeeper/zutil.func·001()
/Users/petar/code.google.com/p/gocircuit/src/circuit/kit/zookeeper/zutil/util.go:51 +0x42
created by circuit/kit/zookeeper/zutil.DialUntilReady
/Users/petar/code.google.com/p/gocircuit/src/circuit/kit/zookeeper/zutil/util.go:58 +0x26d

*/

func main() {
	flag.Parse()

	println("Dialing Zookeeper…")
	conn, err := zutil.DialUntilReady(*flagZookeepers)
	if err != nil {
		panic(err)
	}

	println("Installing watch.")
	w := zutil.InstallWatch(conn, "/")

	// First call never blocks
	println("Fetching children first time.")
	children, stat, err := w.ChildrenChange(nil, 0)
	if err != nil {
		panic(err)
	}
	println(fmt.Sprintf("children=%#v", children))

	println("Sleeping 2 seconds before second watch …")
	time.Sleep(2 * time.Second)

	// Second call has all substance
	children, _, err = w.ChildrenChange(stat, 0)
	if err != nil {
		panic(err)
	}
	println(fmt.Sprintf("children=%#v", children))
}
